local L=JMacroLocale
local ID,JTYPE,MINLEVEL,LEVEL,COOLDOWN,CHANNELTIME,DURATION = 1,2,3,4,5,6,7
local HPS,MPS,HP,MP,MAXHP,MAXMP,STR,DEX,ITEL,VIL,SPR = 8,9,10,11,12,13,14,15,16,17,18
local CLOSEATTACK,RANGEATTACK,SPELL,HEAL = 19,20,21,22
local CLOSEATTACKCRIT,RANGEATTACKCRIT,SPELLCRIT,HEALCRIT= 23,24,25,26
local MAGICMADE=27

local emp={name="jmacro-nothing"}
emp.eff={}
emp.eff.jtype=JTYPE_FOOD

function UnitHealthPercent(unit)
	return UnitHealth(unit)/UnitHealthMax(unit)
end

function UnitManaPercent(unit)
	return UnitMana(unit)/UnitManaMax(unit)
end

function IsMountedAny()
	return IsMounted() or HasBuff("player","召唤地狱战马")
end

--有没有某物品
function HasItem(name)
	return JMacroBagCount[name]~=nil and JMacroBagCount[name]>0
	--return GetItemCount(name)>0
end

function GetExistingItem(items)
	if(items==nil)then
		return nil
	end
	for i=1,#items do
		if(HasItem(items[i]))then
			return items[i]
		end
	end
end

function HasPet()
	return UnitExists("pet") and not UnitIsDead("pet")
end

function HasDebuff(unit,dispelType)
	local x=1
	local t=GetTime()+1  --1秒后就到时间的debuff不考虑
	local name, rank, icon, count, _dispelType, duration, expires, caster, isStealable = UnitAura(unit, x ,"HARMFUL")
	while (name) do
		if(name and _dispelType and _dispelType==dispelType and expires>t) then
			return true;
		end
		x=x+1;
		name, rank, icon, count, _dispelType, duration, expires, caster, isStealable = UnitAura(unit, x ,"HARMFUL")
	end
	return false
end

--有没有某buff
function HasBuff(unit,name)
	local x=1
	local buff = UnitBuff(unit,x)
	while (buff) do
		if(string.find(buff, name)) then
			return true;
		end
		x=x+1;
		buff = UnitBuff(unit,x)
	end
	return false
end

local function initHealInfo(item,level,healthMax,manaMax)
	local hps,mps = item.eff[HPS] or 0,item.eff[MPS] or 0
	if(hps<1)then hps = hps*100*healthMax end
	if(mps<1)then mps = mps*100*manaMax end
	--角色回血回蓝基本值，不准确
	item.tempHPS=hps+0.48*level + 2
	item.tempMPS=mps+0.76*level + 4.75
	local total = JMacroBagCount[item.name]
	item.overStack= total % item.maxStack
	if(item.overStack==0)then item.overStack=item.maxStack end
	item.overStackFix = 1+math.log(item.overStack);
	--print(item.name.." total:"..total.." max:"..item.maxStack.." over:"..item.overStack.." fix:"..item.overStackFix)
	
	item.tempHPS2=item.tempHPS / item.overStackFix
	item.tempMPS2=item.tempMPS / item.overStackFix
	
	if(item.eff[MAGICMADE])then 
		item.tempHPS2=item.tempHPS*1.5
		item.tempMPS2=item.tempMPS*1.5
	end
	
	--JMacroPrint(item.name..'hps'..item.tempHPS..'hps2:'..item.tempHPS2..'overStackFix'..item.overStackFix)
	return hps,mps
end

function JGetBestFoodWater()
	local level,health,healthMax,mana,manaMax = UnitLevel("player"), UnitHealth("player"),UnitHealthMax("player"),UnitMana("player"),UnitManaMax("player")
	local needHeal,needMana = (healthMax-health)+1,(manaMax-mana)+1
	local powerType, powerToken, altR, altG, altB = UnitPowerType("player")
	if(powerType~=0)then needMana=0.00001 end
	local foodName,waterName,healTime,manaTime,minHealTime,minManaTime,hps,mps,minTime
	emp.tempHPS= 0.48*level + 2
	emp.tempMPS= 0.76*level + 4.75
	emp.tempHPS2=emp.tempHPS/5
	emp.tempMPS2=emp.tempMPS/5
	--JMacroPrint('needHeal'..needHeal)
	--JMacroPrint('level'..level..emp.name..'hps'..emp.tempHPS..'hps2:'..emp.tempHPS2)
	local foodWaters,foods,waters={emp},{emp},{emp}
	for name,item in pairs(JMacroBag) do 
		if((item.minLevel or 0)<=level 
			--and item.subType==L["subtypes"][1]
			and bit.band(item.eff.jtype or 0,JTYPE_FOOD)~=0
			and item.type~=L["type.recipe"]
			and item.subType~=L["subType.meet"]
		)then 

			hps,mps = initHealInfo(item,level,healthMax,manaMax)
			if(hps>0 and mps>0)then 
				foodWaters[#foodWaters+1]=item
			elseif(hps>0)then
				foods[#foods+1]=item
			elseif(mps>0)then 
				waters[#waters+1]=item
			end
			--JMacroPrint(item.name..hps..'mps:'..mps)
		end
	end
	table.sort(foodWaters,function(a,b) return a.tempHPS2>b.tempHPS2 end)
	table.sort(foods,function(a,b) return a.tempHPS2>b.tempHPS2 end)
	table.sort(waters,function(a,b) return a.tempMPS2>b.tempMPS2 end)

	minHealTime = needHeal/foods[1].tempHPS2
	minManaTime = needMana/waters[1].tempMPS2
	minTime = math.max(minHealTime,minManaTime)
	--JMacroPrint('minHeal'..minTime)
	if(#foodWaters>1)then
		local minTime2 = math.max(needHeal/foodWaters[1].tempHPS,needMana/foodWaters[1].tempMPS)
		--JMacroPrint("minHealTime "..minHealTime.." minManaTime "..minManaTime.." minTime2:"..minTime2)
		if(minTime > minTime2)then
			return foodWaters[1].name,foodWaters[1].name
		end
	end
	local mindelta = math.abs(minHealTime-minManaTime)
	waterName=waters[1].name
	foodName = foods[1].name
	--JMacroPrint(foodName..",..."..waterName)
	if(waterName ~= emp.name and foodName ~= emp.name)then
		--if(minHealTime>minManaTime)then
		if(health/healthMax)<(mana/manaMax)then
			for i=2,#waters do
				local delta = math.abs(minHealTime - needMana/waters[i].tempMPS)
				--print(waters[i].name.."delta:"..delta.."mindelta:"..mindelta)
				if(waters[i].eff[MAGICMADE])then delta=(delta*0.75)/item.overStackFix end
				if(delta < mindelta)then
					waterName=waters[i].name
					--JMacroPrint(foodName..","..waterName)
				end
			end
		else
			for i=2,#foods do
				local delta = math.abs(minManaTime - needHeal/foods[i].tempHPS)
				--print(foods[i].name.."delta:"..delta.."mindelta:"..mindelta)
				if(foods[i].eff[MAGICMADE])then delta=(delta*0.75)/item.overStackFix end
				if(delta < mindelta)then
					foodName=foods[i].name
					--JMacroPrint(foodName..","..waterName)
				end
			end
		end
	end
	return foodName,waterName
end


--drink , 队伍喊话，喝点水
function JMacroFoodHandler(macroname,perfix)
	--扫描背包,寻找合适的食物、水、法师水，使用最高级、最少的食物/水,优先使用法师水
	local food,water=JGetBestFoodWater()
	local perf = perfix or "#showtooltip"
	if(food==water)then 
		if(food=="jmacro-nothing")then 
			--return JMacroEdit(macroname,"#showtooltip\n/s Sit...\n/sit")
			return false
		else
			return JMacroEdit(macroname,perf.."\n/use [nocombat]"..food.."\n/jp")
		end
	else
		local text = perf
		if(UnitHealthPercent("player")<UnitManaPercent("player"))then
			if(food~="jmacro-nothing")then 
				text = text .. "\n/use [nocombat]"..food
			end
			if(water~="jmacro-nothing")then 
				text = text .. "\n/use [nocombat]"..water
			end
		else
			if(water~="jmacro-nothing")then 
				text = text .. "\n/use [nocombat]"..water
			end
			if(food~="jmacro-nothing")then 
				text = text .. "\n/use [nocombat]"..food
			end
		end
		return JMacroEdit(macroname,text)
	end
	return false
end

--buff 、猎人守护切换、无则造石、造水、造食
function JMacroBuffHandler()
	--扫描目标或自己已有的buff，决定下一个buff
	
end

--band 自动使用合适的绷带，无目标是宠物，右键是自己，alt是自己 
function JMacroBandageHandler(macroname,perfix)
--[[
80 抗毒药剂x3 小毒囊 1学习 
130 强力抗毒药剂 x3 大毒囊 1 购买 
300 极效抗毒药剂 巨型毒囊 1 购买
]]--
	local perf
	if(perfix)then
		perf = perfix.."\n/stopmacro [combat]"
	else
		perf = "#showtooltip"
	end
	perf= perf.."\n/use [help,nodead][target=player,mod:alt][target=player,button:2][target=pet,nodead][target=player]"
	local bands={"厚灵纹布绷带","灵纹布绷带","厚符文布绷带","符文布绷带","厚魔纹绷带","魔纹绷带","厚丝质绷带","丝质绷带","厚绒线绷带","绒线绷带","厚亚麻绷带","亚麻绷带"};--获取可用band列表，最合适的在最前
	for i=1,#bands do
		if(GetItemCount(bands[i])>0)then
			return JMacroEdit(macroname,perf..bands[i])
		end
	end
	return JMacroEdit(macroname,perf..bands[1])
end

--pet 猎人 治疗、复活、喂食、召唤， 术士 召唤合适的宠物、治疗宠物（非战斗状态用绷带），alt/shift/ctrl切换 
function JMacroPetHandler()
	local text;
	if(hunter)then
		text=""
	elseif(warlock)then
		text=""
	end
end


--heal 药剂，治疗石优先
function JMacroHPHandler(macroname)
	local level,health,healthMax,mana,manaMax = UnitLevel("player"), UnitHealth("player"),UnitHealthMax("player"),UnitMana("player"),UnitManaMax("player")
	local potions={}
	for name,item in pairs(JMacroBag) do 
		if((item.minLevel or 0)<=level 
			--and item.subType==L["subtypes"][2]
			--and bit.band(item.eff.jtype or 0,JTYPE_FOOD)~=0
			and item.eff[CHANNELTIME]==1
			and item.type~=L["type.recipe"]
			and item.eff[HPS]~=nil
			and item.eff[HPS]>0
			--and item.subType~=L["subType.meet"]
		)then 
			initHealInfo(item,level,healthMax,manaMax)
			potions[#potions+1]=item
		end
	end
	
	if(#potions>0)then
		table.sort(potions,function(a,b) return a.tempHPS2>b.tempHPS2 end)
		return JMacroEdit(macroname,"#showtooltip\n/use "..potions[1].name)
	end
	return JMacroEdit(macroname,"#showtooltip")
end

--mana 药剂
function JMacroMPHandler(macroname)
	local level,health,healthMax,mana,manaMax = UnitLevel("player"), UnitHealth("player"),UnitHealthMax("player"),UnitMana("player"),UnitManaMax("player")
	local potions={}
	for name,item in pairs(JMacroBag) do 
		if((item.minLevel or 0)<=level 
			--and item.subType==L["subtypes"][2]
			--and bit.band(item.eff.jtype or 0,JTYPE_FOOD)~=0
			and item.eff[CHANNELTIME]==1
			and item.type~=L["type.recipe"]
			and item.eff[MPS]~=nil
			and item.eff[MPS]>0
			--and item.subType~=L["subType.meet"]
		)then 
			initHealInfo(item,level,healthMax,manaMax)
			potions[#potions+1]=item
		end
	end
	if(#potions>0)then
		table.sort(potions,function(a,b) return a.tempMPS2>b.tempMPS2 end)
		return JMacroEdit(macroname,"#showtooltip\n/use "..potions[1].name)
	end
	return JMacroEdit(macroname,"#showtooltip")
end
